package com.imooc.pay.service.impl;

import com.google.gson.Gson;
import com.imooc.pay.dao.PayInfoMapper;
import com.imooc.pay.enums.PayPlatFormEnum;
import com.imooc.pay.pojo.PayInfo;
import com.imooc.pay.service.PayService;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.enums.OrderStatusEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;


import java.math.BigDecimal;

@Slf4j
@Service
public class PayServiceImpl implements PayService {
    public static final String QUEUE_PAY_NOTIFY = "payNotify";
    @Autowired
    private BestPayServiceImpl bestPayService;

    @Autowired
    private PayInfoMapper payInfoMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public PayResponse create(String orderId, BigDecimal amount, BestPayTypeEnum bestPayTypeEnum) {
        // 写入数据库
        payInfoMapper.insertSelective(new PayInfo(Long.parseLong(orderId),
                PayPlatFormEnum.getByBestPayTypeEnum(bestPayTypeEnum).getCode(),
                OrderStatusEnum.NOTPAY.name(),
                amount));

        PayRequest payRequest = new PayRequest();
        payRequest.setOrderName("best pay sdk");
        payRequest.setOrderId(orderId);
        payRequest.setOrderAmount(amount.doubleValue());
        payRequest.setPayTypeEnum(bestPayTypeEnum);

        PayResponse response = bestPayService.pay(payRequest);
        log.info("发起支付 response = {}", response);
        return response;
    }

    @Override
    public String asyncNotify(String notifyData) {
        // 1.检查签名
        PayResponse payResponse = bestPayService.asyncNotify(notifyData);
        log.info("异步通知 payResponse={}", payResponse);

        // 2.校验金额
        String orderId = payResponse.getOrderId();
        Double orderAmount = payResponse.getOrderAmount();
        PayInfo payInfo = payInfoMapper.queryByOrderNo(Long.parseLong(orderId));
        if (payInfo == null) {
            throw new RuntimeException("通过OrderNo查询到的结果是 null");
        }

        // 如果订单的状态不是“已支付”
        if (!payInfo.getPlatformStatus().equals(OrderStatusEnum.SUCCESS.name())) {
            if (payInfo.getPayAmount().compareTo(BigDecimal.valueOf(orderAmount)) != 0) {
                throw new RuntimeException("异步通知中的金额和数据库力的金额不一致，orderNo=" + orderId);
            }
            // 3.修改数据库中订单的状态，改成已支付
            payInfo.setPlatformStatus(OrderStatusEnum.SUCCESS.name());
            payInfo.setPlatformNumber(payResponse.getOutTradeNo());
            payInfoMapper.updateByPrimaryKeySelective(payInfo);
        }

        //TODO 发送MQ消息，mall项目接受MQ消息
        amqpTemplate.convertAndSend(QUEUE_PAY_NOTIFY, new Gson().toJson(payInfo));


        if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.WX) {
            //4. 告诉微信不要再通知了
            return "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
        }else if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY) {
            //4. 告诉支付宝不要再通知了
            return "success";
        }

        throw new RuntimeException("异步通知中错误的支付平台");
    }

    @Override
    public PayInfo queryByOrderId(String orderId) {
        return payInfoMapper.queryByOrderNo(Long.parseLong(orderId));
    }
}
